using System;
using System.Data;
using System.Configuration;
using CodeWork.Library.Data;
using System.Data.Common;
using System.Collections.Generic;
using System.Data.SqlTypes;
using CodeWork.Library;
using System.Text;
using System.Data.SqlClient;

/// <summary>
/// ORM object that maps to tbl_Address
/// </summary>
namespace EasyCommerce.DAL
{
    public class Address : SqlServerDAO
    {
        /// <summary>
        /// Self table parameters
        /// </summary>
        private int _id;
		private string _addressTitle;
		private string _addressLines;
		private string _city;
		private string _state;
		private string _country;
		private string _phone;
		private string _zipCode;
		private string _addressHolderFirstName;
		private string _addressHolderLastName;

        /// <summary>
        /// Foriegn key parameters
        /// </summary>
        private List<UserProfile> _userUserProfile;
		private bool _isUserUserProfileLoaded;
		private List<UserProfile> _billingUserProfile;
		private bool _isBillingUserProfileLoaded;
		private List<UserProfile> _shippingUserProfile;
		private bool _isShippingUserProfileLoaded;
		

        /// <summary>
        /// Self table properties
        /// </summary>
		public int Id
		{
			get { return this._id; }
			set { this._id = value; }
		}

		public string AddressTitle
		{
			get { return this._addressTitle; }
			set { this._addressTitle = value; }
		}

		public string AddressLines
		{
			get { return this._addressLines; }
			set { this._addressLines = value; }
		}

		public string City
		{
			get { return this._city; }
			set { this._city = value; }
		}

		public string State
		{
			get { return this._state; }
			set { this._state = value; }
		}

		public string Country
		{
			get { return this._country; }
			set { this._country = value; }
		}

		public string Phone
		{
			get { return this._phone; }
			set { this._phone = value; }
		}

		public string ZipCode
		{
			get { return this._zipCode; }
			set { this._zipCode = value; }
		}

		public string AddressHolderFirstName
		{
			get { return this._addressHolderFirstName; }
			set { this._addressHolderFirstName = value; }
		}

		public string AddressHolderLastName
		{
			get { return this._addressHolderLastName; }
			set { this._addressHolderLastName = value; }
		}
		
        /// <summary>
        /// Foreign key properties, loaded on demand only
        /// </summary>
        public List<UserProfile> UserUserProfile
		{
			get
			{
				if (!this._isUserUserProfileLoaded)
				{
					List<Condition> conditions = new List<Condition>();
					conditions.Add(new Condition("user_address_id", ConditionOperator.Equal,this._id, JoinOperator.FirstValue));
					UserProfile userProfile = new UserProfile();
					this._userUserProfile = userProfile.Load(conditions);
					this._isUserUserProfileLoaded = true;
				}
				return this._userUserProfile;
			}
			set
			{
				this._userUserProfile = value;
				this._isUserUserProfileLoaded = true;
			}
		}
		public List<UserProfile> BillingUserProfile
		{
			get
			{
				if (!this._isBillingUserProfileLoaded)
				{
					List<Condition> conditions = new List<Condition>();
					conditions.Add(new Condition("billing_address_id", ConditionOperator.Equal,this._id, JoinOperator.FirstValue));
					UserProfile userProfile = new UserProfile();
					this._billingUserProfile = userProfile.Load(conditions);
					this._isBillingUserProfileLoaded = true;
				}
				return this._billingUserProfile;
			}
			set
			{
				this._billingUserProfile = value;
				this._isBillingUserProfileLoaded = true;
			}
		}
		public List<UserProfile> ShippingUserProfile
		{
			get
			{
				if (!this._isShippingUserProfileLoaded)
				{
					List<Condition> conditions = new List<Condition>();
					conditions.Add(new Condition("shipping_address_id", ConditionOperator.Equal,this._id, JoinOperator.FirstValue));
					UserProfile userProfile = new UserProfile();
					this._shippingUserProfile = userProfile.Load(conditions);
					this._isShippingUserProfileLoaded = true;
				}
				return this._shippingUserProfile;
			}
			set
			{
				this._shippingUserProfile = value;
				this._isShippingUserProfileLoaded = true;
			}
		}
		

        /// <summary>
        /// Empty Constructor
        /// </summary>
        public Address() { }

        /// <summary>
        /// Parameterized constructor
        /// </summary>
        /// <param name="id"></param>
		/// <param name="addressTitle"></param>
		/// <param name="addressLines"></param>
		/// <param name="city"></param>
		/// <param name="state"></param>
		/// <param name="country"></param>
		/// <param name="phone"></param>
		/// <param name="zipCode"></param>
		/// <param name="addressHolderFirstName"></param>
		/// <param name="addressHolderLastName"></param>
        public Address
        (
            int id,
			string addressTitle,
			string addressLines,
			string city,
			string state,
			string country,
			string phone,
			string zipCode,
			string addressHolderFirstName,
			string addressHolderLastName
        )
        {
            this._id = id;
			this._addressTitle = addressTitle;
			this._addressLines = addressLines;
			this._city = city;
			this._state = state;
			this._country = country;
			this._phone = phone;
			this._zipCode = zipCode;
			this._addressHolderFirstName = addressHolderFirstName;
			this._addressHolderLastName = addressHolderLastName;
        }

        /// <summary>
        /// Static save method. Saves the current instance in the table using the provided values using the
        /// primary key id. Expects that the Id is a primary key of an existing record in table.
        /// </summary>
        /// <param name="id"></param>
		/// <param name="addressTitle"></param>
		/// <param name="addressLines"></param>
		/// <param name="city"></param>
		/// <param name="state"></param>
		/// <param name="country"></param>
		/// <param name="phone"></param>
		/// <param name="zipCode"></param>
		/// <param name="addressHolderFirstName"></param>
		/// <param name="addressHolderLastName"></param>
        /// <returns>Boolean result as success or failure</returns>
        [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, true)]
        public static bool Save
        (
            int id,
			string addressTitle,
			string addressLines,
			string city,
			string state,
			string country,
			string phone,
			string zipCode,
			string addressHolderFirstName,
			string addressHolderLastName
        )
        {
            Address address = new Address();
            address.Id = id;
			address.AddressTitle = addressTitle;
			address.AddressLines = addressLines;
			address.City = city;
			address.State = state;
			address.Country = country;
			address.Phone = phone;
			address.ZipCode = zipCode;
			address.AddressHolderFirstName = addressHolderFirstName;
			address.AddressHolderLastName = addressHolderLastName;

            return address.Save();
        }

        /// <summary>
        /// Saves the current instance and returns result
        /// </summary>
        /// <returns>Boolean result as success or failure</returns>
        public override bool Save()
        {
			SqlCommand command = (SqlCommand)CreateCommand();
			
            AddCommandParameter(command, "@ReturnValue", SqlDbType.Int, 0, ParameterDirection.ReturnValue, null);
            AddCommandParameter(command, "@Id", SqlDbType.Int, 0, ParameterDirection.Input, Id);
			AddCommandParameter(command, "@AddressTitle", SqlDbType.NVarChar, 250, ParameterDirection.Input, AddressTitle);
			AddCommandParameter(command, "@AddressLines", SqlDbType.NVarChar, -1, ParameterDirection.Input, AddressLines);
			AddCommandParameter(command, "@City", SqlDbType.NVarChar, 250, ParameterDirection.Input, City);
			AddCommandParameter(command, "@State", SqlDbType.NVarChar, 250, ParameterDirection.Input, State);
			AddCommandParameter(command, "@Country", SqlDbType.NVarChar, 250, ParameterDirection.Input, Country);
			AddCommandParameter(command, "@Phone", SqlDbType.NVarChar, 50, ParameterDirection.Input, Phone);
			AddCommandParameter(command, "@ZipCode", SqlDbType.NVarChar, 50, ParameterDirection.Input, ZipCode);
			AddCommandParameter(command, "@AddressHolderFirstName", SqlDbType.NVarChar, 250, ParameterDirection.Input, AddressHolderFirstName);
			AddCommandParameter(command, "@AddressHolderLastName", SqlDbType.NVarChar, 250, ParameterDirection.Input, AddressHolderLastName);

            SetCommandType(command, CommandType.StoredProcedure, StoreProcedureName.Sp_Address_Save.ToString());

            int returnValue = (int)GetOneData(command);
            return (returnValue == 0 ? false : true);
        }

        /// <summary>
        /// Saves the current instance based on provided conditions. This method assumes that
        /// conditions are provided in correct order and in proper format.
        /// </summary>
        /// <param name="conditions">Custom condition based on which to match data</param>
        /// <returns>Boolean result as success or failure</returns>
        [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, true)]
        public bool Save(List<Condition> conditions)
        {
			SqlCommand command = (SqlCommand)CreateCommand();
			
            PrepareConditionalParameters(command, conditions);

            AddCommandParameter(command, "@NewAddressTitle", SqlDbType.NVarChar, 250, ParameterDirection.Input, AddressTitle);
			AddCommandParameter(command, "@NewAddressLines", SqlDbType.NVarChar, -1, ParameterDirection.Input, AddressLines);
			AddCommandParameter(command, "@NewCity", SqlDbType.NVarChar, 250, ParameterDirection.Input, City);
			AddCommandParameter(command, "@NewState", SqlDbType.NVarChar, 250, ParameterDirection.Input, State);
			AddCommandParameter(command, "@NewCountry", SqlDbType.NVarChar, 250, ParameterDirection.Input, Country);
			AddCommandParameter(command, "@NewPhone", SqlDbType.NVarChar, 50, ParameterDirection.Input, Phone);
			AddCommandParameter(command, "@NewZipCode", SqlDbType.NVarChar, 50, ParameterDirection.Input, ZipCode);
			AddCommandParameter(command, "@NewAddressHolderFirstName", SqlDbType.NVarChar, 250, ParameterDirection.Input, AddressHolderFirstName);
			AddCommandParameter(command, "@NewAddressHolderLastName", SqlDbType.NVarChar, 250, ParameterDirection.Input, AddressHolderLastName);

            SetCommandType(command, CommandType.StoredProcedure, StoreProcedureName.Sp_Address_SaveConditional.ToString());

            int returnValue = (int)GetOneData(command);
            return (returnValue == 0 ? false : true);
        }

        /// <summary>
        /// Static creational method. This method actually adds a new entry in the table with
        /// the provided information.
        /// </summary>
        /// <param name="addressTitle"></param>
		/// <param name="addressLines"></param>
		/// <param name="city"></param>
		/// <param name="state"></param>
		/// <param name="country"></param>
		/// <param name="phone"></param>
		/// <param name="zipCode"></param>
		/// <param name="addressHolderFirstName"></param>
		/// <param name="addressHolderLastName"></param>
        /// <returns>Instance of the created object</returns>
        [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Update, true)]
        public static Address Create
        (
            string addressTitle,
			string addressLines,
			string city,
			string state,
			string country,
			string phone,
			string zipCode,
			string addressHolderFirstName,
			string addressHolderLastName
        )
        {
            Address address = new Address();
            address.AddressTitle = addressTitle;
			address.AddressLines = addressLines;
			address.City = city;
			address.State = state;
			address.Country = country;
			address.Phone = phone;
			address.ZipCode = zipCode;
			address.AddressHolderFirstName = addressHolderFirstName;
			address.AddressHolderLastName = addressHolderLastName;

            return (address.Create() ? address : null);
        }

        /// <summary>
        /// Instance creational method. Inserts the current object as a new entry in table.
        /// </summary>
        /// <returns>Boolean result as success or failure</returns>
        public override bool Create()
        {
			SqlCommand command = (SqlCommand)CreateCommand();
			
            AddCommandParameter(command, "@ReturnValue", SqlDbType.Int, 0, ParameterDirection.ReturnValue, null);
            AddCommandParameter(command, "@AddressTitle", SqlDbType.NVarChar, 250, ParameterDirection.Input, AddressTitle);
			AddCommandParameter(command, "@AddressLines", SqlDbType.NVarChar, -1, ParameterDirection.Input, AddressLines);
			AddCommandParameter(command, "@City", SqlDbType.NVarChar, 250, ParameterDirection.Input, City);
			AddCommandParameter(command, "@State", SqlDbType.NVarChar, 250, ParameterDirection.Input, State);
			AddCommandParameter(command, "@Country", SqlDbType.NVarChar, 250, ParameterDirection.Input, Country);
			AddCommandParameter(command, "@Phone", SqlDbType.NVarChar, 50, ParameterDirection.Input, Phone);
			AddCommandParameter(command, "@ZipCode", SqlDbType.NVarChar, 50, ParameterDirection.Input, ZipCode);
			AddCommandParameter(command, "@AddressHolderFirstName", SqlDbType.NVarChar, 250, ParameterDirection.Input, AddressHolderFirstName);
			AddCommandParameter(command, "@AddressHolderLastName", SqlDbType.NVarChar, 250, ParameterDirection.Input, AddressHolderLastName);

            SetCommandType(command, CommandType.StoredProcedure, StoreProcedureName.Sp_Address_Create.ToString());

            Id = (int)GetOneData(command);
            return (Id == 0 ? false : true);
        }

        /// <summary>
        /// Static deletion method. Deletes a record from table using the provided primary key id.
        /// </summary>
        /// <param name="id">Primary key</param>
        /// <returns>Boolean result as success or failure</returns>
        [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Delete, true)]
        public static bool Delete(int id)
        {
            Address address = new Address();
            address.Id = id;

            return address.Delete();
        }

        /// <summary>
        /// Static deletion method. Deletes a list record from table using the provided primary keys id.
        /// </summary>
        /// <param name="ids">List of primarky key id</param>
        /// <returns>Boolean result as success or failure</returns>
        [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Delete, true)]
        public static bool Delete(List<int> ids)
        {
            string csvIds = Utility.MakeCSV(ids);

            Address address = new Address();

            return address.Delete(csvIds);
        }

        /// <summary>
        /// Static deletion method. Deletes records from table using provided conditions.
        /// </summary>
        /// <param name="conditions">Custom condition based on which to match data</param>
        /// <returns>Boolean result as success or failure</returns>
        public static bool Delete(List<Condition> conditions)
        {
            Address address = new Address();

            return address.ConditionalDelete(conditions);
        }

        /// <summary>
        /// This is helper method for conditional delete method above. Not for other general use.
        /// </summary>
        /// <param name="conditions">Custom condition based on which to match data</param>
        /// <returns>Boolean result as success or failure</returns>
        private bool ConditionalDelete(List<Condition> conditions)
        {
			SqlCommand command = (SqlCommand)CreateCommand();
			
            PrepareConditionalParameters(command, conditions);

            SetCommandType(command, CommandType.StoredProcedure, StoreProcedureName.Sp_Address_DeleteConditional.ToString());

            int returnValue = (int)GetOneData(command);
            return (returnValue == 0 ? false : true);
        }

        /// <summary>
        /// This is a helper method for multiple id delete method. Not for general use.
        /// </summary>
        /// <param name="csvIds">Comma seperated primary key values as string</param>
        /// <returns>Boolean result as success or failure</returns>
        private bool Delete(string csvIds)
        {
			SqlCommand command = (SqlCommand)CreateCommand();
			
            AddCommandParameter(command, "@ReturnValue", SqlDbType.Int, 0, ParameterDirection.ReturnValue, null);
            AddCommandParameter(command, "@Ids", SqlDbType.NVarChar, 500, ParameterDirection.Input, csvIds);

            SetCommandType(command, CommandType.StoredProcedure, StoreProcedureName.Sp_Address_DeleteMultiple.ToString());

            int returnValue = (int)GetOneData(command);
            return (returnValue == 0 ? false : true);
        }

        /// <summary>
        /// Instance deletion method. Deletes the current instance from table.
        /// </summary>
        /// <returns>Boolean result as success or failure</returns>
        public override bool Delete()
        {
			SqlCommand command = (SqlCommand)CreateCommand();
			
            AddCommandParameter(command, "@ReturnValue", SqlDbType.Int, 0, ParameterDirection.ReturnValue, null);
            AddCommandParameter(command, "@Id", SqlDbType.Int, 0, ParameterDirection.Input, Id);

            SetCommandType(command, CommandType.StoredProcedure, StoreProcedureName.Sp_Address_DeleteOne.ToString());

            int returnValue = (int)GetOneData(command);
            return (returnValue == 0 ? false : true);
        }

        /// <summary>
        /// Static selection method. Used for loading a perticular data using primary key id.
        /// </summary>
        /// <param name="id">Primary key</param>
        /// <returns>Instance of the loaded object</returns>
        [System.ComponentModel.DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType.Select, true)]
        public static Address Load(int id)
        {
            Address address = new Address();
            address.Id = id;

            if (address.Load())
                return address;
            else
                return null;
        }

        /// <summary>
        /// Instance selection method that fetches data using paging and sorting and also with 
        /// custom conditions.
        /// </summary>
        /// <param name="oderBy">Sorting order</param>
        /// <param name="startRow">Page start position</param>
        /// <param name="pageSize">Number of maximum record to be shown</param>
        /// <param name="conditions">Custom condition based on which to match data</param>
        /// <returns>List of instances of loaded objects</returns>
        public List<Address> Load(string orderBy, int startRow, int pageSize, List<Condition> conditions)
        {
            List<Address> addresss = new List<Address>();
			
			SqlCommand command = (SqlCommand)CreateCommand();
			
            PrepareConditionalParameters(command, conditions);

            AddCommandParameter(command, "@ReturnValue", SqlDbType.Int, 0, ParameterDirection.ReturnValue, null);
            AddCommandParameter(command, "@OrderBy", SqlDbType.NVarChar, 50, ParameterDirection.Input, orderBy);
            AddCommandParameter(command, "@StartRow", SqlDbType.Int, 0, ParameterDirection.Input, startRow);
            AddCommandParameter(command, "@PageSize", SqlDbType.Int, 0, ParameterDirection.Input, pageSize);

            SetCommandType(command, CommandType.StoredProcedure, StoreProcedureName.Sp_Address_LoadConditionalPaged.ToString());

            List<BaseDAO> dataList = GetListData(command);

            foreach (BaseDAO data in dataList)
            {
                Address address = (Address)data;
                addresss.Add(address);
            }

            return addresss;
        }

        /// <summary>
        /// Counts the number of total record available
        /// </summary>
        /// <param name="conditions">Custom condition based on which to match data</param>
        /// <returns>Count of the records</returns>
        public int LoadCount(List<Condition> conditions)
        {
			SqlCommand command = (SqlCommand)CreateCommand();
			
            PrepareConditionalParameters(command, conditions);

            AddCommandParameter(command, "@ReturnValue", SqlDbType.Int, 0, ParameterDirection.ReturnValue, null);
            SetCommandType(command, CommandType.StoredProcedure, StoreProcedureName.Sp_Address_LoadConditionalPagedCount.ToString());

            int returnValue = (int)GetOneData(command);
            return returnValue;
        }

        /// <summary>
        /// Instance selection method that fetches data using paging and sorting.
        /// </summary>
        /// <param name="oderBy">Sorting order</param>
        /// <param name="startRow">Page start position</param>
        /// <param name="pageSize">Number of maximum record to be shown</param>
        /// <returns>List of instances of loaded objects</returns>
        public List<Address> Load(string orderBy, int startRow, int pageSize)
        {
            List<Address> addresss = new List<Address>();
            
			SqlCommand command = (SqlCommand)CreateCommand();
			
            AddCommandParameter(command, "@ReturnValue", SqlDbType.Int, 0, ParameterDirection.ReturnValue, null);
            AddCommandParameter(command, "@OrderBy", SqlDbType.NVarChar, 50, ParameterDirection.Input, orderBy);
            AddCommandParameter(command, "@StartRow", SqlDbType.Int, 0, ParameterDirection.Input, startRow);
            AddCommandParameter(command, "@PageSize", SqlDbType.Int, 0, ParameterDirection.Input, pageSize);

            SetCommandType(command, CommandType.StoredProcedure, StoreProcedureName.Sp_Address_LoadPaged.ToString());

            List<BaseDAO> dataList = GetListData(command);

            foreach (BaseDAO data in dataList)
            {
                Address address = (Address)data;
                addresss.Add(address);
            }

            return addresss;
        }

        /// <summary>
        /// Counts the number of total record available
        /// </summary>
        /// <returns>Count of the records</returns>
        public int LoadCount()
        {
			SqlCommand command = (SqlCommand)CreateCommand();
			
            AddCommandParameter(command, "@ReturnValue", SqlDbType.Int, 0, ParameterDirection.ReturnValue, null);
            SetCommandType(command, CommandType.StoredProcedure, StoreProcedureName.Sp_Address_LoadPagedCount.ToString());

            int returnValue = (int)GetOneData(command);
            return returnValue;
        }

        /// <summary>
        /// Instance selection method. Used for reloading the current object from table. This method uses
        /// the Id of the current object to load and expects that the Id is correct.
        /// </summary>
        /// <returns>Boolean result as success or failure</returns>
        public override bool Load()
        {
			SqlCommand command = (SqlCommand)CreateCommand();
			
            AddCommandParameter(command, "@ReturnValue", SqlDbType.Int, 0, ParameterDirection.ReturnValue, null);
            AddCommandParameter(command, "@Id", SqlDbType.Int, 0, ParameterDirection.Input, Id);

            SetCommandType(command, CommandType.StoredProcedure, StoreProcedureName.Sp_Address_Load.ToString());

            List<BaseDAO> dataList = GetListData(command);

            foreach (BaseDAO data in dataList)
            {
                Address address = (Address)data;

                this._id = address._id;
				this._addressTitle = address._addressTitle;
				this._addressLines = address._addressLines;
				this._city = address._city;
				this._state = address._state;
				this._country = address._country;
				this._phone = address._phone;
				this._zipCode = address._zipCode;
				this._addressHolderFirstName = address._addressHolderFirstName;
				this._addressHolderLastName = address._addressHolderLastName;

                break;
            }

            return (dataList.Count > 0 ? true : false);
        }

        /// <summary>
        /// Instance selection method. Used for loading multiple record based on provided conditions.
        /// </summary>
        /// <param name="conditions">Custom condition based on which to match data</param>
        /// <returns>List of instances of loaded objects</returns>
        public List<Address> Load(List<Condition> conditions)
        {
            List<Address> addresss = new List<Address>();

			SqlCommand command = (SqlCommand)CreateCommand();
			
            PrepareConditionalParameters(command, conditions);

            SetCommandType(command, CommandType.StoredProcedure, StoreProcedureName.Sp_Address_LoadConditional.ToString());

            List<BaseDAO> dataList = GetListData(command);

            foreach (BaseDAO data in dataList)
            {
                Address address = (Address)data;
                addresss.Add(address);
            }

            return addresss;
        }

        /// <summary>
        /// Prepares the conditional parameters for use with Create/ Save/ Load/ Delete methods
        /// that use custom condition. Prepares the user Command object for using conditions.
        /// </summary>
        /// <param name="conditions">Custom condition based on which to match data</param>
        private void PrepareConditionalParameters(SqlCommand command, List<Condition> conditions)
        {
            StringBuilder condition = new StringBuilder();

            object id = null;
			object addressTitle = null;
			object addressLines = null;
			object city = null;
			object state = null;
			object country = null;
			object phone = null;
			object zipCode = null;
			object addressHolderFirstName = null;
			object addressHolderLastName = null;

            for (int i = 0; i < conditions.Count; i++)
            {
                string fieldName = Utility.ToHungarianNotation(conditions[i].FieldName);

                if (conditions[i].JoiningCondition == JoinOperator.FirstValue)
                {
                    condition.Append("WHERE ");
                }
                else if (conditions[i].JoiningCondition == JoinOperator.And)
                {
                    condition.Append(" AND ");
                }
                else if (conditions[i].JoiningCondition == JoinOperator.Or)
                {
                    condition.Append(" OR ");
                }

                condition.Append(conditions[i].FieldName).Append(" ").Append(Condition.MapCondition(conditions[i].ConditionalOperator)).Append("@" + fieldName);

                if ((conditions[i].ConditionalOperator == ConditionOperator.Like ||
                    conditions[i].ConditionalOperator == ConditionOperator.NotLike))
                {
                    if (string.IsNullOrEmpty(conditions[i].Value.ToString()))
                        conditions[i].Value = "%%%";
                    else
                        conditions[i].Value = "%" + conditions[i].Value.ToString() + "%";
                }

                if (fieldName == TableColumns.Id.ToString())
                    id = conditions[i].Value;
                else if (fieldName == TableColumns.AddressTitle.ToString())
					addressTitle = conditions[i].Value;
				else if (fieldName == TableColumns.AddressLines.ToString())
					addressLines = conditions[i].Value;
				else if (fieldName == TableColumns.City.ToString())
					city = conditions[i].Value;
				else if (fieldName == TableColumns.State.ToString())
					state = conditions[i].Value;
				else if (fieldName == TableColumns.Country.ToString())
					country = conditions[i].Value;
				else if (fieldName == TableColumns.Phone.ToString())
					phone = conditions[i].Value;
				else if (fieldName == TableColumns.ZipCode.ToString())
					zipCode = conditions[i].Value;
				else if (fieldName == TableColumns.AddressHolderFirstName.ToString())
					addressHolderFirstName = conditions[i].Value;
				else if (fieldName == TableColumns.AddressHolderLastName.ToString())
					addressHolderLastName = conditions[i].Value;
            }

            AddCommandParameter(command, "@Condition", SqlDbType.NVarChar, 2000, ParameterDirection.Input, condition.ToString());
            AddCommandParameter(command, "@Id", SqlDbType.Int, 0, ParameterDirection.Input, id);
			AddCommandParameter(command, "@AddressTitle", SqlDbType.NVarChar, 250, ParameterDirection.Input, addressTitle);
			AddCommandParameter(command, "@AddressLines", SqlDbType.NVarChar, -1, ParameterDirection.Input, addressLines);
			AddCommandParameter(command, "@City", SqlDbType.NVarChar, 250, ParameterDirection.Input, city);
			AddCommandParameter(command, "@State", SqlDbType.NVarChar, 250, ParameterDirection.Input, state);
			AddCommandParameter(command, "@Country", SqlDbType.NVarChar, 250, ParameterDirection.Input, country);
			AddCommandParameter(command, "@Phone", SqlDbType.NVarChar, 50, ParameterDirection.Input, phone);
			AddCommandParameter(command, "@ZipCode", SqlDbType.NVarChar, 50, ParameterDirection.Input, zipCode);
			AddCommandParameter(command, "@AddressHolderFirstName", SqlDbType.NVarChar, 250, ParameterDirection.Input, addressHolderFirstName);
			AddCommandParameter(command, "@AddressHolderLastName", SqlDbType.NVarChar, 250, ParameterDirection.Input, addressHolderLastName);
        }

        /// <summary>
        /// Binds the fetched data from data reader to Objects
        /// </summary>
        /// <param name="reader">Data reader supplied by BaseDAO</param>
        /// <returns>List of object instances that was bound</returns>
        protected override List<BaseDAO> BindData(DbDataReader reader)
        {
            List<BaseDAO> result = new List<BaseDAO>();

			if (reader == null)
                return null;

            while (reader.Read())
            {
                Address address = new Address
                (
					reader["id"] == System.DBNull.Value ? GetIdMinValue : (int)reader["id"],
                    reader["address_title"] == System.DBNull.Value ? string.Empty : (string)reader["address_title"],
					reader["address_lines"] == System.DBNull.Value ? string.Empty : (string)reader["address_lines"],
					reader["city"] == System.DBNull.Value ? string.Empty : (string)reader["city"],
					reader["state"] == System.DBNull.Value ? string.Empty : (string)reader["state"],
					reader["country"] == System.DBNull.Value ? string.Empty : (string)reader["country"],
					reader["phone"] == System.DBNull.Value ? string.Empty : (string)reader["phone"],
					reader["zip_code"] == System.DBNull.Value ? string.Empty : (string)reader["zip_code"],
					reader["address_holder_first_name"] == System.DBNull.Value ? string.Empty : (string)reader["address_holder_first_name"],
					reader["address_holder_last_name"] == System.DBNull.Value ? string.Empty : (string)reader["address_holder_last_name"]
                );

                result.Add(address);
            }
            
            if(!reader.IsClosed)
                reader.Close();

            return result;
        }

        /// <summary>
        /// List of store procedures that this class use
        /// </summary>
        private enum StoreProcedureName
        {
            Sp_Address_Save = 0,
            Sp_Address_Create = 1,
            Sp_Address_DeleteOne = 2,
            Sp_Address_DeleteMultiple = 3,
            Sp_Address_DeleteConditional = 4,
            Sp_Address_SaveConditional = 5,
            Sp_Address_LoadConditional = 6,
            Sp_Address_Load = 7,
            Sp_Address_LoadConditionalPaged = 8,
            Sp_Address_LoadConditionalPagedCount = 9,
            Sp_Address_LoadPaged = 10,
            Sp_Address_LoadPagedCount = 11
        }

        /// <summary>
        /// List of table column names that this class use
        /// </summary>
        private enum TableColumns
        {
            Id = 0,
			AddressTitle = 1,
			AddressLines = 2,
			City = 3,
			State = 4,
			Country = 5,
			Phone = 6,
			ZipCode = 7,
			AddressHolderFirstName = 8,
			AddressHolderLastName = 9
        }
    }
}